package org.project.hint_game;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.io.FileOutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Random;
import java.io.IOException;
import java.net.MalformedURLException;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;
import org.project.server.AsyncLast;
import org.project.server.AsyncLastCallback;
import org.project.server.AsyncSend;
import org.project.server.AsyncSendCallback;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class NewJoinActivity extends Activity implements OnClickListener, AsyncSendCallback, AsyncLastCallback {
		
	private Button m_newGameButton;
	private Button m_joinGameButton;
	private Button m_joinGameCancelButton;
	private Button m_newGameCancelButton;
	private Button m_newGameRefreshButton;
	private Button m_joinGameRefreshButton;
	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	private TextView m_newGameText;
	private TextView m_joinGameText;
	private TextView m_joinedPlayerText;
	private TextView m_joinerUsernameText;
	private TextView m_creatorUsernameText;
	
	private String character_;
	private String turn_;
	private int inLobby_;
	private String returnCard_;
	private int gameStart_;
	private String replyer_;
	private String requester_;
	private String weapon_;
	private String sCardList_;
	private String room_;


	// Websites
	private String preamble = "http://autotextbobby.appspot.com/vshare/";
	private String postGameName_ = preamble+"startgame";
	private String checkStatus_ = preamble+"/view/everything";
	private String changeTurn_ = preamble+"/changeturn";
	private String cardReply_ = preamble+"/upload/cardreply";
	private String cardRequest_ = preamble+"/upload/cardrequest";
	private String addPlayer_ = preamble+"/upload/addplayer";
	private String postCards_ = preamble+"/upload/cardlist";
	
	// Important Data
	private String gameName_;
	
	// Create player list
//	private ArrayList<Player> players_;
	private ArrayList<Integer> cardList_;
	private ArrayList<Integer> m_randomArray;

	// boolean for checking if "create a game" has been clicked once
	boolean m_startGameCheck = false;
	boolean m_joinedStatus = false;

	// for saving data to a file
	private String m_filedata;

	// temporary variable for testing purposes...will probably remove!
	int m_joinedPlayers = 0;

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_new_join);
		this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

		// Initialize lists
//		players_ = new ArrayList<Player>();
		cardList_ = new ArrayList<Integer>();
		m_randomArray = new ArrayList<Integer>();

		// Link variables to UI elements
		m_newGameButton = (Button) findViewById(R.id.newGameButton);
		m_joinGameButton = (Button) findViewById(R.id.joinGameButton);
		m_newGameCancelButton = (Button) findViewById(R.id.newGameCancelButton);
		m_joinGameCancelButton = (Button) findViewById(R.id.joinGameCancelButton);
		m_joinGameRefreshButton = (Button) findViewById(R.id.joinGameRefreshButton);
		m_newGameRefreshButton = (Button) findViewById(R.id.newGameRefreshButton);
		m_newGameText = (TextView) findViewById(R.id.newGameText);
		m_joinGameText = (TextView) findViewById(R.id.joinGameText);
		m_joinedPlayerText = (TextView) findViewById(R.id.playersWaiting);
		m_creatorUsernameText = (TextView) findViewById(R.id.creatorUsernameText);
		m_joinerUsernameText = (TextView) findViewById(R.id.joinerUsernameText);

		// Set button listeners
		m_newGameButton.setOnClickListener(this);
		m_joinGameButton.setOnClickListener(this);
		m_newGameCancelButton.setOnClickListener(this);
		m_joinGameCancelButton.setOnClickListener(this);
		m_newGameRefreshButton.setOnClickListener(this);
		m_joinGameRefreshButton.setOnClickListener(this);

		// Populate lists
		for (int i = 1; i < 7; i++)
			m_randomArray.add(i);
		for (int i = 1; i < 21; i++)
			cardList_.add(i);

		// Get 3 cards (1 person, 1 weapon, 1 room)
		Random rand = new Random();
		int randPerson = rand.nextInt(6) + 1;
		int randWeapon = rand.nextInt(6) + 7;
		int randRoom = rand.nextInt(8) + 13;

		// Debugging
		Log.d("Removing", "randomStuff");
		
		// Remove specified cards from list
		cardList_.remove(randPerson - 1); // 19 items in list
		cardList_.remove(randWeapon - 2); // 18 items in list
		cardList_.remove(randRoom - 3); // 17 items in list
		
		// Debugging
		Log.d("Removed Person", Integer.toString(randPerson -1));
		Log.d("Removed Weapon", Integer.toString(randWeapon -1));
		Log.d("Removed Room", Integer.toString(randRoom-1));

		// Shuffle lists
		shuffleList(m_randomArray);
		shuffleList(cardList_);
	}

	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.newGameButton:
			if (m_startGameCheck) {
				startGame();
			} else {
				newGame();
				serverSendGameName();
			}
			break;
		case R.id.joinGameButton:
			joinGame();
			break;
		case R.id.newGameCancelButton:
			newGameCancelButton();
			break;
		case R.id.joinGameCancelButton:
			joinGameCancelButton();
			break;
		case R.id.joinGameRefreshButton:
			refreshPressed();
			break;
		case R.id.newGameRefreshButton:
			refreshPressed();
			break;
		default:
			break;
		}

	}	
	
	//REFRESH HAS BEEN PRESSED
	public void refreshPressed(){
		Log.d("refreshbutton", "Pressed button");
		serverGetDetails();
		if (gameStart_ == 1){
			m_newGameText.setText("Game Started!");
//			serverSendCards();
			//serverSendCards();
			setupCharacters();
			setupCards();
			m_filedata += ":1,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0";
			m_filedata += ":blank,blank,blank,blank,blank,blank,blank,blank,blank,blank,blank,blank,blank,blank,blank,blank,blank,blank,blank,blank";
			writeData();
			Intent intent = new Intent(NewJoinActivity.this,
					RoomSelectActivity.class);
			intent.putExtra("currentRoom", -1);
			startActivity(intent);
			
		}
	}
	
	public void newGame() {
		// alert dialog box for establishing a new game
		AlertDialog.Builder alert = new AlertDialog.Builder(this);
		alert.setTitle("Create a new game");
		alert.setMessage("New game name:");

		// for user input!!
		final EditText input = new EditText(this);
		alert.setView(input);

		// the 2 buttons!! ("create" and "cancel")
		alert.setPositiveButton("Create",
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int whichButton) {
						String value = input.getText().toString();
						gameName_ = value;
						m_newGameText.setText("Your game name is: " + value);
						m_newGameButton.setText("Start Game");
						m_joinedPlayers = 1;
						m_joinedPlayerText.setText(Integer
								.toString(m_joinedPlayers)
								+ "/6 players in lobby");
						m_startGameCheck = true;
//						createUsername(1);
						serverSendGameName();
					}
				});

		alert.setNegativeButton("Cancel",
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int whichButton) {
					}
				});

		alert.show();
	}

	// to join an existing game!
	// ***NOTE: will probably change this code entirely!
	// I just have sample test code in here to show players
	// being added to lobby.
	// *****Extra Note: Add dialog box to input game name!!
	public void joinGame() {		
		// alert dialog box for establishing a new game
				AlertDialog.Builder alert = new AlertDialog.Builder(this);
				alert.setTitle("Join a game");
				alert.setMessage("Input game name:");

				// for user input!!
				final EditText input = new EditText(this);
				alert.setView(input);

				// the 2 buttons!! ("create" and "cancel")
				alert.setPositiveButton("Join",
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int whichButton) {
								String value = input.getText().toString();
								gameName_ = value;
								serverAddPlayer();
							}
						});

				alert.setNegativeButton("Cancel",
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int whichButton) {
							}
						});

				alert.show();
				
	}

	// Add players to the game
	public void serverAddPlayer(){
		// Construct information to send
		List<NameValuePair> sAddPlayer = new ArrayList<NameValuePair>();
		sAddPlayer.add(new BasicNameValuePair("gamename", gameName_));
		// Send information
		serverSendStuff(sAddPlayer, addPlayer_);
	}
	
	// can only be called after a game is created!
	public void startGame() {
		m_newGameText.setText("Game Started!");
		setupCharacters();
		setupCards();
		m_filedata += ":1,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0";
		m_filedata += ":blank,blank,blank,blank,blank,blank,blank,blank,blank,blank,blank,blank,blank,blank,blank,blank,blank,blank,blank,blank";
		writeData();
		Intent intent = new Intent(NewJoinActivity.this,
				RoomSelectActivity.class);
		intent.putExtra("currentRoom", -1);
		startActivity(intent);
	}
 
	public void setupCards(){
//		int start = sCardList_.indexOf("P2:");
//		String data = sCardList_.substring(start);
//		int end = data.indexOf(";");
//		String data2 = data.substring(3, end);
//
//		ArrayList<Integer> theList = new ArrayList<Integer>();
	}
	
	public void writeData() {
		try {

			FileOutputStream fos = openFileOutput("hint_game_data.txt",
					Context.MODE_PRIVATE);
			fos.write(m_filedata.getBytes());
			fos.close();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			// textMsg.setText(e.toString());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			// textMsg.setText(e.toString());
		}
	}
	
	public void serverSendGameName(){
		// Construct information to send
		List<NameValuePair> sGameInfo = new ArrayList<NameValuePair>();
		sGameInfo.add(new BasicNameValuePair("gamename", gameName_));
		// Send information
		serverSendStuff(sGameInfo, postGameName_);
	}
	
	// Get information from the server
	public void serverGetDetails(){
		HttpGet pullRequest = new HttpGet(checkStatus_);
		AsyncLast request = new AsyncLast(pullRequest, this);
		request.execute();
	}
	
	// Sends a string to the webserver
	public void serverSendStuff(List<NameValuePair> data, String url){
		HttpClient client = new DefaultHttpClient();
		HttpPost post = new HttpPost(url);
		try {
			post.setEntity(new UrlEncodedFormEntity(data));
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		AsyncSend object = new AsyncSend(client, post, this);
		
		// Debugging
		Log.d("Sending", "data...");
		
		object.execute();
	}
	
	public void setupCharacters() {
		m_filedata = "";
		for (int i = 0; i < m_joinedPlayers; i++) {
			m_filedata += m_randomArray.get(i);
			if (i < (m_joinedPlayers - 1)) {
				m_filedata += ",";
			}
		}
	}

	// for canceling a new game
	// if hit during "Create a game", send back to title screen
	public void newGameCancelButton() {
		if (m_startGameCheck) {
			m_startGameCheck = false;
			m_joinedPlayerText.setText(" ");
			m_newGameText.setText("Start a New Game!");
			m_newGameButton.setText("Create a Game");
			m_creatorUsernameText.setText(" ");
			m_joinedPlayers = 0;
		} else {
			Intent intent = new Intent(NewJoinActivity.this,
					TitleScreenActivity.class);
			startActivity(intent);
		}
	}

	// for canceling a joined game
	public void joinGameCancelButton() {
		if (m_joinedStatus) {
			m_joinedStatus = false;
			--m_joinedPlayers;
			m_joinGameText.setText("Join and Existing Game!");
			m_joinerUsernameText.setText(" ");
			m_joinedPlayerText.setText(Integer.toString(m_joinedPlayers)
					+ "/6 players in lobby");
		} else {
			Intent intent = new Intent(NewJoinActivity.this,
					TitleScreenActivity.class);
			startActivity(intent);
		}
	}


	// Method To Assign Cards
	public void serverSendCards() {
		int it;
		StringBuilder sCardList = new StringBuilder();
		if (inLobby_ == 2) {
			Log.d("CardSetup", "2 Player");
			// Player 1 gets 8 cards
			sCardList.append("P1:");
			for (it = 0; it < 8; it++){
				sCardList.append(cardList_.get(it));
				if (it == 7)
					sCardList.append(";");
				else
					sCardList.append(",");
			}
			// Player 2 gets 9 cards
			sCardList.append("P2:");
			for (; it < 17; it++){
				sCardList.append(cardList_.get(it));
				if (it == 16)
					sCardList.append(";");
				else
					sCardList.append(",");
			}
		} else if (inLobby_ == 3) {
			// Player 1 gets 5 cards
			sCardList.append("P1:");
			for (it = 0; it < 5; it++){
				sCardList.append(cardList_.get(it));
				if (it == 4)
					sCardList.append(";");
				else
					sCardList.append(",");
			}
			// Player 2 gets 6 cards
			sCardList.append("P2:");
			for (; it < 11; it++){
				sCardList.append(cardList_.get(it));
				if (it == 10)
					sCardList.append(";");
				else
					sCardList.append(",");
			}
			// Player 3 gets 6 cards
			sCardList.append("P3:");
			for (; it < 17; it++){
				sCardList.append(cardList_.get(it));
				if (it == 16)
					sCardList.append(";");
				else
					sCardList.append(",");
			}
		} else if (inLobby_ == 4) {
			// Player 1 gets 4 cards
			sCardList.append("P1:");
			for (it = 0; it < 4; it++){
				sCardList.append(cardList_.get(it));
				if (it == 3)
					sCardList.append(";");
				else
					sCardList.append(",");
			}
			// Player 2 gets 4 cards
			sCardList.append("P2:");
			for (; it < 8; it++){
				sCardList.append(cardList_.get(it));
				if (it == 7)
					sCardList.append(";");
				else
					sCardList.append(",");
			}
			// Player 3 gets 4 cards
			sCardList.append("P3:");
			for (; it < 12; it++){
				sCardList.append(cardList_.get(it));
				if (it == 11)
					sCardList.append(";");
				else
					sCardList.append(",");
			}
			// Player 4 gets 5 cards
			sCardList.append("P4:");
			for (; it < 17; it++){
				sCardList.append(cardList_.get(it));
				if (it == 16)
					sCardList.append(";");
				else
					sCardList.append(",");
			}
		} else if (inLobby_ == 5) {
			// Player 1 gets 3 cards
			sCardList.append("P1:");
			for (it = 0; it < 3; it++){
				sCardList.append(cardList_.get(it));
				if (it == 2)
					sCardList.append(";");
				else
					sCardList.append(",");
			}
			// Player 2 gets 3 cards
			sCardList.append("P2:");
			for (; it < 6; it++){
				sCardList.append(cardList_.get(it));
				if (it == 5)
					sCardList.append(";");
				else
					sCardList.append(",");
			}
			// Player 3 gets 3 cards
			sCardList.append("P3:");
			for (; it < 9; it++){
				sCardList.append(cardList_.get(it));
				if (it == 8)
					sCardList.append(";");
				else
					sCardList.append(",");
			}
			// Player 4 gets 4 cards
			sCardList.append("P4:");
			for (; it < 13; it++){
				sCardList.append(cardList_.get(it));
				if (it == 12)
					sCardList.append(";");
				else
					sCardList.append(",");
			}
			// Player 5 gets 4 cards
			sCardList.append("P5:");
			for (; it < 17; it++){
				sCardList.append(cardList_.get(it));
				if (it == 16)
					sCardList.append(";");
				else
					sCardList.append(",");
			}
		} else if (inLobby_ == 6) {
			// Player 1 gets 2 cards
			sCardList.append("P1:");
			for (it = 0; it < 2; it++){
				sCardList.append(cardList_.get(it));
				if (it == 1)
					sCardList.append(";");
				else
					sCardList.append(",");
			}
			// Player 2 gets 3 cards
			sCardList.append("P2:");
			for (; it < 5; it++){
				sCardList.append(cardList_.get(it));
				if (it == 4)
					sCardList.append(";");
				else
					sCardList.append(",");
			}
			// Player 3 gets 3 cards
			sCardList.append("P3:");
			for (; it < 8; it++){
				sCardList.append(cardList_.get(it));
				if (it == 7)
					sCardList.append(";");
				else
					sCardList.append(",");
			}
			// Player 4 gets 3 cards
			sCardList.append("P4:");
			for (; it < 11; it++){
				sCardList.append(cardList_.get(it));
				if (it == 10)
					sCardList.append(";");
				else
					sCardList.append(",");
			}
			// Player 5 gets 3 cards
			sCardList.append("P5:");
			for (; it < 14; it++){
				sCardList.append(cardList_.get(it));
				if (it == 13)
					sCardList.append(";");
				else
					sCardList.append(",");
			}
			// Player 6 gets 3 cards
			sCardList.append("P6:");
			for (; it < 17; it++){
				sCardList.append(cardList_.get(it));
				if (it == 16)
					sCardList.append(";");
				else
					sCardList.append(",");
			}
		}
		
		// Debugging
		Log.d("sCardList", sCardList.toString());
				
		// Send the string to the server
		List<NameValuePair> sCardList2 = new ArrayList<NameValuePair>();
		sCardList2.add(new BasicNameValuePair("gamename", gameName_));
		sCardList2.add(new BasicNameValuePair("cards", sCardList.toString()));
		serverSendStuff(sCardList2, postCards_);
	}

	// shuffle algorithm---------------------------------
	private void shuffleList(List theList) {
		int n = theList.size();
		Random random = new Random();
		random.nextInt();
		for (int i = 0; i < n; i++) {
			int change = i + random.nextInt(n - i);
			swap(i, change, theList);
		}
	}
	private void swap(int i, int change, List<Object> theList) {
		Object helper = theList.get(i);
		theList.set(i, theList.get(change));
		theList.set(change, helper);
	}
	// ---------------------------------------------------

	@Override
	public void onBackPressed() {
	}

	public void onResponse3(HttpResponse resp) {
		Log.d("Response3", "Success");	
	}
	public void onError3(Exception e) {
		Log.d("Response3", "Error");
	}
	public void onResponse4(HttpResponse resp, String content) {
		int bound = content.indexOf(gameName_);
		content = content.substring(bound, content.length());
		bound = content.indexOf("{");
		if (bound != -1){
			String sub= content.substring(bound);
			bound = sub.indexOf("}");
			sub = sub.substring(0, bound+1);
			Log.d("String before JSON", sub);
			try {
				JSONObject obj = new JSONObject(sub);
				Log.d("obj:", obj.toString());

				String inLobby = obj.getString("inLobby:");
				replyer_ = obj.getString("replyer:");
				requester_ = obj.getString("requester:");
					
				returnCard_ = obj.getString("returnCard:");
				turn_ = obj.getString("turn:");
			
				weapon_ = obj.getString("weapon:");
				character_ = obj.getString("character:");
				room_ = obj.getString("room:");
			
				sCardList_ = obj.getString("cardList:");
				String gameStart = obj.getString("gameStart:");
			
				// get number out of string
				gameStart = gameStart.replace("[", "");
				gameStart = gameStart.replace("]", "");
				gameStart_ = Integer.parseInt(gameStart);
				inLobby = inLobby.replace("[", "");
				inLobby = inLobby.replace("]", "");
				inLobby_ = Integer.parseInt(inLobby);
				m_joinedPlayerText.setText(inLobby + "/6 players in lobby");
				
				Log.d("Response4", inLobby);
			} catch (JSONException e) {
				e.printStackTrace();
				Log.e("Json", "Fail");
			}
		}
		
	}
	public void onError4(Exception e) {
		// TODO Auto-generated method stub
		
	}

}
